<template>
    <div v-clickOutSide="handleHideSelect">
        <a-dropdown :trigger="['click']" :visible="visible" :class="visible ? 'active' : ''" :getPopupContainer="getPopupContainer">
            <flexbox :class="['ant-dropdown-link', 'dropdown-wrap', bordered ? 'bordered' : '']" @click="visible = !visible">
                <!-- 用click控制显示，是因为需要点击范围之外隐藏 -->
                <span class="title-cont"> {{ showTitle }} </span>
                <DownOutlined style="margin-left: 4px" v-if="!disabled" />
            </flexbox>
            <template #overlay>
                <div class="dropdown-body" v-empty="!isEmpty" @click.stop="visible = true">
                    <div style="padding-bottom: 5px">
                        <a class="clear-text" v-if="!isEmpty && !disabled" @click="handleClearAll">清除选择的内容</a>
                    </div>
                    <div style="max-height: 200px; overflow-y: auto" v-if="radio">
                        <a-radio-group :disabled="disabled" v-model:value="selectItemId" @change="handleCheckChange">
                            <flexbox v-for="(item, index) of options" :key="item.id" :class="index === 0 ? '' : 'margin-t-8'">
                                <a-radio :value="item.id" v-fitText>
                                    {{ item.dimensionName || item.system || item.name }}
                                </a-radio>
                            </flexbox>
                        </a-radio-group>
                    </div>
                    <div style="max-height: 200px; overflow-y: auto" v-else>
                        <flexbox v-for="(item, index) of options" :key="item.code" :class="index === 0 ? '' : 'margin-t-8'">
                            <a-checkbox :disabled="disabled" v-model:checked="item.checked" v-fitText @change="handleCheckChange">
                                {{ item.dimensionName || item.system || item.name }}
                            </a-checkbox>
                        </flexbox>
                    </div>
                </div>
            </template>
        </a-dropdown>
    </div>
</template>
<script lang="ts">
import store from '@/store';
import { deepClone } from '@/utils/util';
import { DownOutlined } from '@ant-design/icons-vue';
import { defineComponent, reactive, toRefs, computed, watch } from 'vue';
export default defineComponent({
    components: {
        DownOutlined
    },
    props: {
        max: {
            type: Number,
            default: 2
        },
        searchQuery: {
            type: Object,
            default: () => ({})
        }, //额外的查询参数
        disabled: {
            type: Boolean,
            default: false
        },
        radio: {
            type: Boolean,
            default: false
        },
        checkbox: {
            type: Boolean,
            default: true
        },
        type: {
            type: String,
            default: ''
        },
        title: {
            type: String,
            default: ''
        },
        defaultOptions: {
            type: Array,
            default: () => []
        },
        value: {
            type: [String, Number],
            default: ''
        },
        getPopupContainer: {
            type: Function,
            default: (node) => node.parentNode
        },
        bordered: {
            type: Boolean,
            default: false
        }
    },
    emits: ['update:value', 'change'],
    setup(props, { emit }) {
        const state = reactive<any>({
            options: [],
            selectedKeys: [],
            visible: false,
            isEmpty: true,
            selectItemId: null,
            showTitle: ''
        });
        const getTitle = () => {
            let title = '';
            if (props.radio) {
                const target = state.selectItemId ? state.options.find((item: Recordable) => item.id === state.selectItemId || item.key === state.selectItemId) : null;
                if (target) {
                    title = props.title ? `${props.title}：${target.name}` : `${target.name}`;
                } else {
                    title = props.title ? `${props.title}：${state.options.length ? '全部' : ''}` : `${state.options.length ? '全部' : ''}`;
                }
            } else {
                const targetArr = state.selectedKeys.map((item: Recordable) => item.dimensionName || item.system || item.name);
                if (targetArr.length) {
                    title = props.title ? `${props.title}：${targetArr.join(',')}` : `${targetArr.join(',')}`;
                } else {
                    title = props.title ? `${props.title}：${state.options.length ? '全部' : ''}` : `${state.options.length ? '全部' : ''}`;
                }
            }
            state.showTitle = title;
        };
        const handleCheckChange = () => {
            if (props.radio) {
                const target = state.options.find((item) => item.id === state.selectItemId);
                emit('change', target || null);
                if (target && target.id) {
                    emit('update:value', target.id || null);
                } else {
                    emit('update:value', target || null);
                }
            } else {
                const arr = state.options.filter((item: Recordable) => item.checked);
                state.selectedKeys = [...arr];
                let selectedArr = [];
                if (state.selectedKeys.length) {
                    selectedArr = state.selectedKeys.map((item: Recordable) => item.code || item.id);
                }
                emit('change', selectedArr.length ? selectedArr.join(',') : null);
                emit('update:value', selectedArr.length ? selectedArr.join(',') : null);
            }
            getTitle();
        };
        const handleClearAll = () => {
            state.selectedKeys = [];
            state.selectItemId = null;
            state.options = state.options.map((item: Recordable) => ({
                ...item,
                checked: false
            }));
            emit('update:value', null);
            emit('change', null);
            getTitle();
        };
        const handleHideSelect = () => {
            state.visible = false;
        };
        const initOptions = () => {
            const options = props.defaultOptions.length ? deepClone(props.defaultOptions) : store.getters.dicOptions[props.type];
            if (options && options.length) {
                state.options = options.map((item: Recordable) => {
                    const checked = state.selectedKeys.length ? state.selectedKeys.some((elem) => elem.code === item.code) : false;
                    return { ...item, checked };
                });
            } else {
                state.options = [];
            }
        };
        const init = () => {
            if (props.radio) {
                state.selectItemId = props.value;
            } else {
                state.selectedKeys = [];
            }
            initOptions();
            state.isEmpty = state.options ? !state.options.length : true;
            getTitle();
        };
        // 1.初始化init 2.重置数据时,要重新恢复checked：false
        watch(
            () => props.value,
            (n) => {
                if (n === null) {
                    init();
                } else {
                    if (props.radio) {
                        state.selectItemId = props.value;
                    }
                    if (state.options.length) {
                        getTitle();
                    }
                }
            }
        );
        // defaultOptions是请求数据的情况
        watch(
            () => props.defaultOptions,
            () => {
                init();
            }
        );
        init();
        return {
            ...toRefs(state),
            handleCheckChange,
            handleClearAll,
            handleHideSelect
        };
    }
});
</script>
<style lang="less" scoped>
@import './styles/index.less';
.bordered {
    border: 1px solid #d9d9d9 !important;
}
</style>
